import { type } from "os";

export interface webStConfig {
  url: string;
  message: string;
  onopen: callbackFn;
  onmessage: callbackFn;
  onclose: callbackFn;
  onerror: callbackFn;
}

type callbackFn = (e: any) => void;
type wsType = WebSocket | null | undefined;
class WebSt {
  private ws: wsType;
  private url: string;
  private message: string;
  private onopen: callbackFn;
  private onmessage: callbackFn;
  private onclose: callbackFn;
  private onerror: callbackFn;
  private limitReConnectNum: number = 5; //Z最多重新连接的次数
  private reConnectNum: number = 1; //重连的计数
  private reConnectBeginTime: number = 0; // 重新连接开始时间
  private isHeartFlat: boolean = false; //心跳检查状态
  private isReconnect: boolean = false; //重连的状态
  private timeout: number = 5000; //连接超时的时间
  private reConnectTimer: any;
  private beatHeartInteval: any;
  constructor(config: webStConfig) {
    const { url, message, onopen, onmessage, onclose, onerror } = config;
    this.url = url;
    this.message = message;
    this.onopen = onopen;
    this.onmessage = onmessage;
    this.onclose = onclose;
    this.onerror = onerror;
  }

  //初始化的方法
  init() {
    const _self = this;
    window.WebSocket = window.WebSocket;
    if (!window.WebSocket) {
      console.error("浏览器不支持WebSocket");
      return;
    }
    this.ws = new WebSocket(this.url);
    this.ws.onopen = function(e) {
      _self.isHeartFlat = true;
      _self.onopen(e);
      _self.startBeatHeart();
    };
    this.ws.onmessage = function(e) {
      _self.isHeartFlat = true;
      _self.onmessage(e);
    };
    this.ws.onclose = function(e) {
      _self.onclose(e);
    };
    this.ws.onerror = function(e) {
      //心跳值为false
      _self.isHeartFlat = false;
      _self.onerror(e);
      if (_self.reConnectNum <= _self.limitReConnectNum) {
        //开始重连
        console.error("WebSocket连接出错，正在重连...");
        clearTimeout(_self.reConnectTimer);
        //2 秒检测一次链接状态
        _self.reConnectTimer = setTimeout(function() {
          if (_self.reConnectNum == 1) {
            _self.reConnectBeginTime = new Date().getTime(); //重连开始的时间
          }

          console.log("尝试第" + _self.reConnectNum + "次重连");
          _self.isReconnect = true; //重连状态这是为true
          _self.reConnect(); //重新连接

          //如果心跳值为true，则重连成功
          if (_self.isHeartFlat) {
            clearTimeout(_self.reConnectTimer);
            _self.reConnectTimer = null;
          }
        }, 2000);
      } else {
        console.error("重连次数超出设定值，不再重连，请检查配置项");
      }
    };
  }

  startBeatHeart() {
    if (typeof this.message !== "undefined") {
        clearInterval(this.beatHeartInteval);
      this.beatHeartInteval = setInterval(() => {
        this.send(this.message);
      }, 1000);
    }
  }

  reConnect() {
    let _self = this;
    //如果没有触发重连操作，则不执行
    if (!this.isReconnect) return;

    //判断重连超时，若超时，则不再重连
    if (
      new Date().getTime() - _self.reConnectBeginTime >
      _self.timeout * 1000
    ) {
      console.error("websocket重连超时");
      this.isReconnect = false;
      //清除重连延时器
      clearTimeout(_self.reConnectTimer);
      _self.reConnectTimer = null;
      return;
    }

    //重连计数器
    _self.reConnectNum++;
    _self.init();
  }

  send(message: any) {
    const _self = this;
    //如果没有传值，则默认发送配置的默认消息
    this.ws && this.ws.send(message);
  }

  close(){
    this.ws&&this.ws.close();
    this.beatHeartInteval&&clearInterval(this.beatHeartInteval);
    this.reConnectTimer&&clearTimeout(this.reConnectTimer);
    this.ws =null;
  }
}


export default WebSt;
